"""
Copyright 2012 Wieser Dietmar, Margit Mutschlechner.

This file is part of Multimedia Social Networking Platform.

Multimedia Social Networking Platform is free software: 
you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

Multimedia Social Networking Platform is distributed
in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with Multimedia Social Networking Platform.  
If not, see <http://www.gnu.org/licenses/>.

"""

from threading import Thread
from msnp.service.network import NetworkLock, BackupController, \
    NetworkController, CustodyQueue
from msnp.persistence import PersistenceController

##########################
## execute remote calls ##
##########################

def sendBackup(backupContent):
    """This function processes the backup.
    
    If an error occurred the database will be cleaned and all low level peers are removed.
    
    Args:
        backupContent: The BackupContent instance.
    """
    NetworkLock.acquireSendBackupLock()
    try:
        if BackupController.processBackup(backupContent) == False:
            #if the processing fails I have perhaps some shifted low levels and some of the backup already processed
            #-> remove everything if an error occurred
            PersistenceController.cleanDatabase()
            NetworkController.getMySelf().removeAllLowLevelPeers()
            CustodyQueue.deleteAllMessages()
    finally:
        NetworkLock.releaseSendBackupLock()
        
def backupCallback(backups):
    """This function is called during a finish-crash procedure if a peer has a needed backup for the new successor.
    
    Args:
        backups: A list of BackupContent instances.
    """
    #lock is in the method
    BackupController.processBackupCallback(backups)
    
##############################
## threads for remote calls ##
##############################

class SendBackupThread(Thread):
    """Thread to send the backup contents.

    Attributes:
        __backupContent: The BackupContent instance.
    """
    
    def __init__(self, backupContent):
        """the init method"""
        Thread.__init__(self)
        self.__backupContent = backupContent
    
    def run(self):
        """This method forwards the call to the sendBackup function."""
        sendBackup(self.__backupContent)

class BackupCallbackThread(Thread):
    """Thread that runs the function to collect missing backups.

    Attributes:
        __backups: The list of BackupContent instances.
    """
    
    def __init__(self, backups):
        """the init method"""
        Thread.__init__(self)
        self.__backups = backups

    def run(self):
        """This method forwards the call to the backupCallback function."""
        backupCallback(self.__backups)

#####################
## execute threads ##
#####################

def executeSendBackup(backupContent):
    """This function starts a thread for sending the backup.
    
    Args:
        backupContent: The BackupContent instance.
    """
    
    sendBackupThread = SendBackupThread(backupContent)
    sendBackupThread.start()
    
def executeBackupCallback(backups):
    """This function starts a thread for collecting missing backups.
    
    Args:
        backups: The list of BackupContent instances.
    """
    
    backupCallbackThread = BackupCallbackThread(backups)
    backupCallbackThread.start()
    
